<?php

namespace App\Http\Controllers\WF\Systems;

use DB;
use Config;
use Hash;
use Log;
use Carbon\Carbon;
use Ramsey\Uuid\Uuid;
use App\Http\Controllers\WF\ApiController;
use Illuminate\Http\Request;
use Jishulin\WorkFlowEngine\Tools\Tools;
use Jishulin\WorkFlowEngine\Tools\Birts;
use Jishulin\WorkFlowEngine\Tools\Jobs;

class WorkFlowController extends ApiController
{
    public function getWorkFlowList(Request $request)
    {
        $page = (int)$request->input('page', 1);
        $limit = $request->input('limit', $this->limit);
        $offest = ($page - 1) * $limit;
        $keyword = $request->input('keyword', '');
        $whereArray = null;

        $whereArray[] = ['wf01003', '=', $this->apiUser['company_id'], 'AND'];

        if ($keyword) {
            $whereArray[] = ['wf01002', 'like', "%{$keyword}%", 'AND'];
        }

        $where['arr'] = $whereArray;
        $orderBy = [['created_at', 'ASC']];
        $res = Tools::getInstance()->getWorkFlowListPagination($offest, $limit, $where, $orderBy);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        $jsonData = $res['data'];

        return $this->jsonReturns(10000, $this->success, $jsonData);
    }

    public function workFlowCrd(Request $request)
    {
        $param = $request->all();

        if (!$param['wf01002']) {
            return $this->jsonReturns(99999, trans('wf.WF-Work-Flow-Name-Cannot-Empty'));
        }

        $flowId = Uuid::uuid1()->getHex();
        $flowName = $param['wf01002'];
        $res = Tools::getInstance()->workFlowCrd($flowId, $flowName, $this->apiUser['company_id']);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data'] ?? []);
    }

    public function getWorkFlowByFlowId(Request $request)
    {
        $flowId = $request->input('flowId', '');
        // Jobs::getInstance()->jobConfigCrd($flowId, []);
        // exit;
        $res = Tools::getInstance()->getWorkFlowByFlowId($flowId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function workFlowEdt(Request $request)
    {
        $flowId = $request->input('wf01001');
        $flowName = $request->input('wf01002');

        $res = Tools::getInstance()->workFlowEdt($flowId, $flowName);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function workFlowSts(Request $request)
    {
        $flowId = $request->input('flowId');
        $status = $request->input('status');

        $tools = Tools::getInstance();

        $res = $status ? $tools->workFlowEnabled($flowId) : $tools->workFlowDisabled($flowId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getWorkNodesTreeByFlowId(Request $request)
    {
        $flowId = $request->input('flowId');

        $tools = Tools::getInstance();

        $res = $tools->getWorkNodesTreeByFlowId($flowId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getBirtList(Request $request)
    {
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');

        $birts = Birts::getInstance();

        $res = $birts->getBirtListByFlowNodeId($flowId, $nodeId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function birtCrd(Request $request)
    {
        $param = $request->all();
        // 处理报表配置信息
        $birtConfig = [];
        $single = [];
        if (isset($param['single']) && count($param['single'])) {
            foreach ($param['single'] as $k => $v) {
                $single[] = [(int)$v['type'], (string)$v['field']];
            }
        }
        $birtConfig['single'] = $single;

        $multi = [];
        if (isset($param['multi']) && count($param['multi'])) {
            foreach ($param['multi'] as $k => $v) {
                $field = \rtrim(str_replace('；', ';', $v['field']), ';');
                $fieldArr = [];
                if (!empty($field)) {
                    $fieldStrArr = \explode(';', $field);
                    foreach ($fieldStrArr as $strK => $strV) {
                        $strArr = \explode('=', $strV);
                        $fieldArr[] = [$strArr[1], $strArr[0]];
                    }
                    $multi[$v['key']] = $fieldArr;
                }
            }
        }
        $birtConfig['table'] = $multi;

        $mapList = [
            'flowId' => $param['flowId'],
            'nodeId' => $param['nodeId'],
            'uuid' => Uuid::uuid1()->getHex(),
            'birtName' => $param['wf04004'],
            'birtSrc' => isset($param['wf04005']) && count($param['wf04005']) ? $param['wf04005'][0]['url'] : '',
            'birtConfig' => $birtConfig,
            'birtType' => $param['wf04007'],
            'birtTransPdf' => $param['wf04008'],
            'birtIsSingleDetail' => $param['wf04009'],
            'birtStatus' => $param['wf04010'],
            'birtOrders' => $param['wf04011'] ?? 10,
        ];

        $birts = Birts::getInstance();

        $res = $birts->birtCrd($mapList);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function birtEdt(Request $request)
    {
        $param = $request->all();
        // 处理报表配置信息
        $birtConfig = [];
        $single = [];
        if (isset($param['single']) && count($param['single'])) {
            foreach ($param['single'] as $k => $v) {
                $single[] = [(int)$v['type'], (string)$v['field']];
            }
        }
        $birtConfig['single'] = $single;

        $multi = [];
        if (isset($param['multi']) && count($param['multi'])) {
            foreach ($param['multi'] as $k => $v) {
                $field = \rtrim(str_replace('；', ';', $v['field']), ';');
                $fieldArr = [];
                if (!empty($field)) {
                    $fieldStrArr = \explode(';', $field);
                    foreach ($fieldStrArr as $strK => $strV) {
                        $strArr = \explode('=', $strV);
                        $fieldArr[] = [$strArr[1], $strArr[0]];
                    }
                    $multi[$v['key']] = $fieldArr;
                }
            }
        }
        $birtConfig['table'] = $multi;

        $mapList = [
            'birtName' => $param['wf04004'],
            'birtSrc' => isset($param['wf04005']) && count($param['wf04005']) ? $param['wf04005'][0]['url'] : '',
            'birtConfig' => $birtConfig,
            'birtType' => $param['wf04007'],
            'birtTransPdf' => $param['wf04008'],
            'birtIsSingleDetail' => $param['wf04009'],
            'birtStatus' => $param['wf04010'],
            'birtOrders' => $param['wf04011'] ?? 10,
        ];

        $birts = Birts::getInstance();

        $res = $birts->birtEdt($param['wf04003'], $mapList);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function birtRmv(Request $request)
    {
        $birtUuid = $request->input('uuid');

        $birts = Birts::getInstance();

        $res = $birts->birtRmvByUuid($birtUuid);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function birtSts(Request $request)
    {
        $birtUuid = $request->input('uuid');
        $status = $request->input('status');

        $birts = Birts::getInstance();

        $res = $status ? $birts->birtEnabled($birtUuid) : $birts->birtDisabled($birtUuid);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getBirtByUuid(Request $request)
    {
        $birtUuid = $request->input('uuid');

        $birts = Birts::getInstance();

        $res = $birts->getBirtByUuid($birtUuid);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        $birtData = (array)$res['data'];
        $config = json_decode($birtData['wf04006'], true);
        if (isset($config['single']) && count($config['single'])) {
            $single = $config['single'];
            $singleData = [];
            foreach ($single as $k => $v) {
                $singleData[] = ['type' => $v[0], 'field' => $v[1]];
            }
            $birtData['single'] = $singleData;
        } else {
            $birtData['single'] = [];
        }

        if (isset($config['table']) && count($config['table'])) {
            $multi = $config['table'];
            $multiData = [];
            foreach ($multi as $k => $v) {
                $fieldStr = '';
                foreach ($v as $fk => $fv) {
                    $fieldStr .= $fv[1] . '=' . $fv[0] . ';';
                }
                $multiData[] = ['key' => $k, 'field' => $fieldStr];
            }
            $birtData['multi'] = $multiData;
        } else {
            $birtData['multi'] = [];
        }

        if ($birtData['wf04005']) {
            $birtData['wf04005'] = [
                [
                    'name' => $birtData['wf04004'],
                    'url' => $birtData['wf04005']
                ]
            ];
        } else {
            $birtData['wf04005'] = [];
        }

        return $this->jsonReturns(10000, $this->success, $birtData);
    }

    public function birtSimulation(Request $request)
    {
        $birtUuid = $request->input('uuid');
        $birts = Birts::getInstance();

        $birtData['simulation'] = true;

        $res = $birts->birtPrintByUuid($birtUuid, $birtData);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getJobConfigsTreeByFlowId(Request $request)
    {
        $flowId = $request->input('flowId');

        $jobs = Jobs::getInstance();

        $res = $jobs->getJobConfigsTreeByFlowId($flowId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function  jobConfigCrd(Request $request)
    {
        $flowId = $request->input('flowId');

        $mapData = [
            'table' => $request->input('table'),
            'comment' => $request->input('label'),
        ];

        $jobs = Jobs::getInstance();

        $res = $jobs->jobConfigCrd($flowId, $mapData);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function  jobConfigEdt(Request $request)
    {
        $flowId = $request->input('flowId');

        $mapData = [
            'table' => $request->input('table'),
            'comment' => $request->input('label'),
        ];

        $jobs = Jobs::getInstance();

        $res = $jobs->jobConfigEdt($flowId, $mapData);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getJobConfigsMaxColumn(Request $request)
    {
        $flowId = $request->input('flowId');
        $table = $request->input('table');

        $jobs = Jobs::getInstance();

        $res = $jobs->getJobConfigsMaxColumn($flowId, $table);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getJobConfigsList(Request $request)
    {
        $flowId = $request->input('flowId');
        $table = $request->input('table');

        $jobs = Jobs::getInstance();

        $res = $jobs->getJobConfigsList($flowId, $table);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function jobConfigSave(Request $request)
    {
        $param = $request->all();

        $jobs = Jobs::getInstance();

        $res = $jobs->jobConfigSave($param);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function jobConfigRmv(Request $request)
    {
        $flowId = $request->input('flowId');
        $table = $request->input('table');
        $column = $request->input('column');

        $jobs = Jobs::getInstance();

        $res = $jobs->jobConfigRmv($flowId, $table, $column);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function jobTableRmv(Request $request)
    {
        $flowId = $request->input('flowId');
        $table = $request->input('table');

        $jobs = Jobs::getInstance();

        $res = $jobs->jobTableRmv($flowId, $table);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getWorkNodeByFlowId(Request $request)
    {
        $flowId = $request->input('flowId');

        $res = Tools::getInstance()->getWorkNodeByFlowId($flowId);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getNodeColumnsConfig(Request $request)
    {
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');

        $jobs = Jobs::getInstance();

        $res = $jobs->getNodeColumnsConfig($flowId, $nodeId);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function nodeColumnsConfigSave(Request $request)
    {
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');
        $type = $request->input('type');
        $target = $request->input('target');

        $jobs = Jobs::getInstance();

        $res = $jobs->nodeColumnsConfigSave($type, $flowId, $nodeId, $target);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getWrokFlowGlobalByKey(Request $request)
    {
        $flowId = $request->input('flowId');
        $key = $request->input('key');

        $res = Tools::getInstance()->getWrokFlowGlobalByKey($flowId, $key);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function workFlowGlobalConfigSave(Request $request)
    {
        $param = $request->all();

        $res = Tools::getInstance()->workFlowGlobalConfigSave($param);

        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getWorkFlowProcessScript(Request $request)
    {
        $flowId = $request->input('flowId');
        return response()->download('./../packages/jishulin/workflowengine/src/Log/logs/sql/' . $flowId . '.sql');
    }

    public function getWorkFlowUpgradeScript(Request $request)
    {
        $flowId = $request->input('flowId');
    }

    public function getNodeColumnExamConfig(Request $request)
    {
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');

        $jobs = Jobs::getInstance();

        $res = $jobs->getNodeColumnExamConfig($flowId, $nodeId);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getFormDesignList(Request $request)
    {
        $flowId = $request->input('flowId');

        $res = Tools::getInstance()->getFormDesignList($flowId);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function formDesignConfigCrd(Request $request)
    {
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');
        $formName = $request->input('formName');
        $firstShow = $request->input('firstShow');
        $formStatus = $request->input('formStatus');

        $res = Tools::getInstance()->formDesignConfigCrd($flowId, $nodeId, $formName, $firstShow, $formStatus);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function formDesignConfigEdt(Request $request)
    {
        $formId = $request->input('formId');
        $flowId = $request->input('flowId');
        $nodeId = $request->input('nodeId');
        $formName = $request->input('formName');
        $firstShow = $request->input('firstShow');
        $formStatus = $request->input('formStatus');

        $res = Tools::getInstance()->formDesignConfigEdt($formId, $flowId, $nodeId, $formName, $firstShow, $formStatus);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function formDesignConfigSts(Request $request)
    {
        $formId = $request->input('formId');
        $flowId = $request->input('flowId');
        $formStatus = $request->input('formStatus');

        $res = Tools::getInstance()->formDesignConfigSts($formId, $flowId, $formStatus);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function formDesignConfigRmv(Request $request)
    {
        $formId = $request->input('formId');
        $flowId = $request->input('flowId');

        $res = Tools::getInstance()->formDesignConfigRmv($formId, $flowId);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success);
    }

    public function getFormDesignConfigByFormId(Request $request)
    {
        $formId = $request->input('formId');
        $res = Tools::getInstance()->getFormDesignConfigByFormId($formId);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function formDesignConfigSave(Request $request)
    {
        $flowId = $request->input('flowId');
        $formId = $request->input('formId');
        $formConfig = $request->input('formConfig');

        $res = Tools::getInstance()->formDesignConfigSave($flowId, $formId, $formConfig);
        if ($res['error']) {
            return $this->jsonReturns(50000, $res['message']);
        }

        return $this->jsonReturns(10000, $this->success, $res['data']);
    }

    public function getJobsColumnByFlowId(Request $request)
    {
        $flowId = $request->input('flowId');

        try {
            $res = Birts::getInstance()->exportWorkFlowJobCloumnsByFlowId($flowId);

            if ($res['error']) {
                return $this->jsonReturns(50000, $res['message']);
            }
        } catch (\Exception $e) {
            Log::error((string)$e);
            return $this->jsonReturns(50000, $e->getMessage());
        }
    }
}
